<!DOCTYPE html>
<html lang="zh-CN" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
<head th:replace="~{fragments/layout :: head('Zipkin链路跟踪测试')}"></head>
<body>
    <!-- 导航栏 -->
    <nav th:replace="~{fragments/layout :: navbar}"></nav>
    
    <!-- 页面内容 -->
    <div th:replace="~{fragments/layout :: content(~{::main})}">
        <main>
            <!-- 标题 -->
            <div class="container mt-4">
                <h1 class="mb-4">Zipkin分布式链路跟踪测试</h1>
                <p class="lead">本页面用于测试Zipkin分布式链路跟踪功能，通过不同的测试场景查看请求的流转路径和耗时情况。</p>
                <hr>
                
                <!-- 测试卡片 -->
                <div class="row">
                    <div class="col-md-4">
                        <div class="card mb-4">
                            <div class="card-header bg-primary text-white">
                                <h5 class="mb-0">简单调用测试</h5>
                            </div>
                            <div class="card-body">
                                <p>测试最基本的链路跟踪功能，返回单个服务的信息。</p>
                                <button id="simpleTraceBtn" class="btn btn-primary">执行简单调用</button>
                                <div class="mt-3">
                                    <div class="d-flex align-items-center">
                                        <span>调用状态：</span>
                                        <span id="simpleStatus" class="ms-2 badge bg-secondary">未调用</span>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                    
                    <div class="col-md-4">
                        <div class="card mb-4">
                            <div class="card-header bg-info text-white">
                                <h5 class="mb-0">复杂链路测试</h5>
                            </div>
                            <div class="card-body">
                                <p>测试多个服务之间的调用链路，并可设置处理延迟。</p>
                                <div class="mb-3">
                                    <label for="delayInput" class="form-label">处理延迟(毫秒)</label>
                                    <input type="number" class="form-control" id="delayInput" value="500" min="0" max="5000">
                                </div>
                                <button id="complexTraceBtn" class="btn btn-info">执行复杂调用</button>
                                <div class="mt-3">
                                    <div class="d-flex align-items-center">
                                        <span>调用状态：</span>
                                        <span id="complexStatus" class="ms-2 badge bg-secondary">未调用</span>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                    
                    <div class="col-md-4">
                        <div class="card mb-4">
                            <div class="card-header bg-danger text-white">
                                <h5 class="mb-0">异常测试</h5>
                            </div>
                            <div class="card-body">
                                <p>测试调用链路中出现异常的情况，观察异常在Zipkin中的显示。</p>
                                <button id="errorTraceBtn" class="btn btn-danger">执行异常调用</button>
                                <div class="mt-3">
                                    <div class="d-flex align-items-center">
                                        <span>调用状态：</span>
                                        <span id="errorStatus" class="ms-2 badge bg-secondary">未调用</span>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
                
                <!-- 结果展示 -->
                <div class="card mb-4">
                    <div class="card-header bg-dark text-white d-flex justify-content-between align-items-center">
                        <h5 class="mb-0">调用结果</h5>
                        <a href="http://localhost:9411" target="_blank" class="btn btn-sm btn-light">打开Zipkin控制台</a>
                    </div>
                    <div class="card-body">
                        <pre id="traceResult" class="bg-light p-3 rounded">未执行调用</pre>
                    </div>
                </div>
                
                <!-- 调用历史 -->
                <div class="card mb-4">
                    <div class="card-header bg-success text-white d-flex justify-content-between align-items-center">
                        <h5 class="mb-0">调用历史</h5>
                        <button id="clearHistoryBtn" class="btn btn-sm btn-light">清空历史</button>
                    </div>
                    <div class="card-body">
                        <div class="table-responsive">
                            <table class="table table-striped table-hover">
                                <thead>
                                    <tr>
                                        <th>#</th>
                                        <th>时间</th>
                                        <th>类型</th>
                                        <th>延迟</th>
                                        <th>端口</th>
                                        <th>处理时间</th>
                                        <th>状态</th>
                                    </tr>
                                </thead>
                                <tbody id="historyTableBody">
                                    <!-- 历史记录将通过JavaScript添加 -->
                                </tbody>
                            </table>
                        </div>
                    </div>
                </div>
                
                <!-- 技术说明 -->
                <div class="card mb-4">
                    <div class="card-header bg-secondary text-white">
                        <h5 class="mb-0">Zipkin链路跟踪说明</h5>
                    </div>
                    <div class="card-body">
                        <p>Zipkin是一个分布式链路跟踪系统，用于收集分布式系统中的时序数据，解决微服务架构中的延迟问题。主要特点：</p>
                        <ul>
                            <li>提供可视化界面，展示服务调用链路</li>
                            <li>记录每个请求的处理时间，帮助发现性能瓶颈</li>
                            <li>跟踪请求在不同服务间的流转路径</li>
                            <li>支持各种常见的库和框架</li>
                            <li>可以分析出哪些服务调用频繁或者存在问题</li>
                        </ul>
                        <div class="alert alert-info">
                            <h5>使用说明：</h5>
                            <ol>
                                <li>点击上方按钮执行不同类型的调用</li>
                                <li>点击"打开Zipkin控制台"访问Zipkin UI</li>
                                <li>在Zipkin UI中搜索TraceID或服务名</li>
                                <li>查看完整的调用链路和耗时分析</li>
                            </ol>
                            <p>注意：请确保Zipkin服务已在本地启动，默认地址为 <a href="http://localhost:9411" target="_blank">http://localhost:9411</a></p>
                        </div>
                    </div>
                </div>
            </div>
        </main>
    </div>
    
    <!-- 页脚 -->
    <footer th:replace="~{fragments/layout :: footer}"></footer>
    
    <!-- 脚本 -->
    <div th:replace="~{fragments/layout :: scripts}"></div>
    
    <!-- Zipkin测试脚本 -->
    <script th:inline="javascript">
        document.addEventListener('DOMContentLoaded', function() {
            // 计数器
            let callCount = 0;
            
            // 获取DOM元素
            const simpleTraceBtn = document.getElementById('simpleTraceBtn');
            const complexTraceBtn = document.getElementById('complexTraceBtn');
            const errorTraceBtn = document.getElementById('errorTraceBtn');
            const clearHistoryBtn = document.getElementById('clearHistoryBtn');
            
            const simpleStatus = document.getElementById('simpleStatus');
            const complexStatus = document.getElementById('complexStatus');
            const errorStatus = document.getElementById('errorStatus');
            
            const delayInput = document.getElementById('delayInput');
            const traceResult = document.getElementById('traceResult');
            const historyTableBody = document.getElementById('historyTableBody');
            
            // 绑定事件
            simpleTraceBtn.addEventListener('click', () => executeTrace('simple'));
            complexTraceBtn.addEventListener('click', () => executeTrace('complex'));
            errorTraceBtn.addEventListener('click', () => executeTrace('error'));
            clearHistoryBtn.addEventListener('click', clearHistory);
            
            // 执行链路跟踪测试
            function executeTrace(type) {
                // 更新状态
                let statusElement;
                let url = '/api/tracing/';
                let params = '';
                
                switch(type) {
                    case 'simple':
                        statusElement = simpleStatus;
                        url += 'simple';
                        break;
                    case 'complex':
                        statusElement = complexStatus;
                        url += 'complex';
                        const delay = delayInput.value || 0;
                        params = `?delay=${delay}`;
                        break;
                    case 'error':
                        statusElement = errorStatus;
                        url += 'error';
                        break;
                }
                
                // 显示加载状态
                statusElement.textContent = '调用中...';
                statusElement.className = 'ms-2 badge bg-warning';
                
                // 记录开始时间
                const startTime = new Date();
                
                // 发起请求
                fetch(url + params)
                    .then(response => response.json())
                    .then(data => {
                        // 计算处理时间
                        const processingTime = data.processingTime || (new Date() - startTime);
                        
                        // 更新状态
                        if (data.status === 'error') {
                            statusElement.textContent = '调用异常';
                            statusElement.className = 'ms-2 badge bg-danger';
                        } else {
                            statusElement.textContent = '调用成功';
                            statusElement.className = 'ms-2 badge bg-success';
                        }
                        
                        // 显示结果
                        traceResult.textContent = JSON.stringify(data, null, 2);
                        
                        // 添加到历史记录
                        addToHistory({
                            time: startTime,
                            type: getTraceTypeName(type),
                            delay: type === 'complex' ? delayInput.value : '-',
                            port: data.port,
                            processingTime: processingTime,
                            status: data.status || 'success'
                        });
                    })
                    .catch(error => {
                        // 更新状态
                        statusElement.textContent = '调用失败';
                        statusElement.className = 'ms-2 badge bg-danger';
                        
                        // 显示错误
                        traceResult.textContent = `调用失败: ${error.message}`;
                        
                        // 添加到历史记录
                        addToHistory({
                            time: startTime,
                            type: getTraceTypeName(type),
                            delay: type === 'complex' ? delayInput.value : '-',
                            port: '-',
                            processingTime: new Date() - startTime,
                            status: 'failed'
                        });
                    });
            }
            
            // 获取调用类型名称
            function getTraceTypeName(type) {
                switch(type) {
                    case 'simple': return '简单调用';
                    case 'complex': return '复杂链路';
                    case 'error': return '异常测试';
                    default: return type;
                }
            }
            
            // 添加到历史记录
            function addToHistory(data) {
                callCount++;
                
                // 创建新行
                const newRow = document.createElement('tr');
                
                // 格式化时间
                const timeStr = data.time.toLocaleTimeString();
                
                // 设置状态样式
                let statusBadge = '';
                switch(data.status) {
                    case 'success':
                        statusBadge = '<span class="badge bg-success">成功</span>';
                        break;
                    case 'error':
                        statusBadge = '<span class="badge bg-warning">异常</span>';
                        break;
                    case 'failed':
                        statusBadge = '<span class="badge bg-danger">失败</span>';
                        break;
                    default:
                        statusBadge = `<span class="badge bg-secondary">${data.status}</span>`;
                }
                
                // 设置行内容
                newRow.innerHTML = `
                    <td>${callCount}</td>
                    <td>${timeStr}</td>
                    <td>${data.type}</td>
                    <td>${data.delay}</td>
                    <td>${data.port}</td>
                    <td>${data.processingTime}ms</td>
                    <td>${statusBadge}</td>
                `;
                
                // 添加到表格
                historyTableBody.insertBefore(newRow, historyTableBody.firstChild);
            }
            
            // 清空历史记录
            function clearHistory() {
                historyTableBody.innerHTML = '';
                callCount = 0;
            }
        });
    </script>
    
    <style>
        pre {
            max-height: 400px;
            overflow-y: auto;
        }
    </style>
</body>
</html> 